<template>
  <div class="plan" v-loading="loading">
    <el-row class="plan-tree" :gutter="20">
      <el-col :xl="5" :lg="5" :md="5" :sm="24" :xs="24">
        <ContentWrap class="h-1/1">
          <el-select v-model="selectPlan" filterable placeholder="请选择" style="width: calc(100% - 68px)"
            @change="changePlan">
            <el-option v-for="item in planList" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
          <el-button type="primary" :icon="Plus" circle size="small" style="margin-left: 10px"
            @click="updateUseCasePlan('create')" v-if="addPermission" />
          <el-button type="primary" :icon="Edit" circle size="small" :disabled="!selectPlan" style="margin-left: 10px"
            @click="updateUseCasePlan('update')" v-if="updatePermission" />
          <el-tree :data="dataSource" ref="treeRef" node-key="id" default-expand-all :expand-on-click-node="false"
            :props="defaultProps" class="tree" :highlight-current="true" :indent="22" @node-click="handleNodeClick">
            <template #default="{ node, data }">
              <!-- 非叶子 -->
              <span style="display: flex; align-items: center" :class="{ current: defaultId == data.id }">
                <span @click.stop="handleExpand(node)">
                  <el-icon v-if="node.expanded" style="margin: 0 6px 0 2px" size="16">
                    <FolderOpened />
                  </el-icon>
                  <el-icon v-else style="margin: 0 6px 0 2px" size="16">
                    <Folder />
                  </el-icon>
                </span>
                <small :title="node.label">{{ node.label }}</small>
                <span v-if="data.caseNum > 0" class="num">
                  （<el-text type="primary" title="总数" @click.stop="handleNumClick(data, '')">{{
    data.caseNum
  }}</el-text>/
                  <el-text type="success" title="执行通过" @click.stop="handleNumClick(data, 2)">{{
    data.successCaseNum
  }}</el-text>/
                  <el-text type="danger" title="失败" @click.stop="handleNumClick(data, 3)">{{
    data.failureCaseNum
  }}</el-text>/
                  <el-text type="warning" title="阻塞" @click.stop="handleNumClick(data, 4)">{{
    data.lockCaseNum
  }}</el-text>/
                  <el-text type="info" title="未执行" @click.stop="handleNumClick(data, 1)">{{
    data.notCaseNum
  }}</el-text>）
                </span>
              </span>
            </template>
          </el-tree>
        </ContentWrap>
      </el-col>
      <el-col :xl="19" :lg="19" :md="19" :sm="24" :xs="24">
        <ContentWrap>
          <!-- 搜索工作栏 -->
          <el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="80px">
            <el-row :gutter="20">
              <el-col :span="6">
                <el-form-item label="执行人员" prop="executeTestUserId">
                  <el-select v-model="queryParams.executeTestUserId" filterable clearable placeholder="请选择执行人员">
                    <el-option v-for="item in memberList" :key="item.id" :label="item.nickname" :value="item.id" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="用例标识" prop="logo">
                  <el-input v-model="queryParams.logo" clearable placeholder="请输入标识" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="开始时间" prop="startTime">
                  <el-date-picker v-model="queryParams.startTime" type="datetime" placeholder="请选择开始时间"
                    format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="用例状态" prop="result">
                  <el-select v-model="queryParams.result" filterable clearable placeholder="请选择用例状态">
                    <el-option v-for="item in getIntDictOptions(DICT_TYPE.TEST_CASE_STATUS)" :key="item.value"
                      :label="item.label" :value="item.value" />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="20">
              <el-col :span="6">
                <el-form-item label="测试类型" prop="testType">
                  <el-select v-model="queryParams.testType" filterable clearable placeholder="请选择类型">
                    <el-option v-for="item in getIntDictOptions(DICT_TYPE.TEST_TYPE)" :key="item.value"
                      :label="item.label" :value="item.value" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="用例名称" prop="name">
                  <el-input v-model="queryParams.name" clearable placeholder="请输入用例名称" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="结束时间" prop="endTime">
                  <el-date-picker v-model="queryParams.endTime" type="datetime" placeholder="请选择结束时间"
                    format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
                </el-form-item>
              </el-col>
              <el-col :span="6" style="padding-left: 25px;">
                <el-form-item>
                  <el-button @click="handleQuery">
                    <Icon class="mr-5px" icon="ep:search" />
                    搜索
                  </el-button>
                  <el-button @click="resetQuery">
                    <Icon class="mr-5px" icon="ep:refresh" />
                    重置
                  </el-button>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </ContentWrap>

        <!-- 列表 -->
        <ContentWrap>
          <el-table :data="list" :show-overflow-tooltip="true">
            <el-table-column align="center" type="index" label="序号" width="70" />
            <el-table-column align="center" label="用例名称" prop="name" />
            <el-table-column align="center" label="标识" prop="logo" />
            <el-table-column align="center" label="测试类型" prop="testType" />
            <el-table-column align="center" label="用例状态" prop="result">
              <template #default="scope">
                <dict-tag :type="DICT_TYPE.TEST_CASE_STATUS" :value="scope.row.result" />
              </template>
            </el-table-column>
            <!-- <el-table-column align="center" label="作者" prop="authorName" /> -->
            <el-table-column align="center" label="执行人员" prop="executeTesterName" />
            <el-table-column align="center" label="测试时间" prop="testDate" />
            <el-table-column align="center" label="操作">
              <template #default="scope">
                <el-button link type="primary" @click="handleInfo(scope.row, 'create')"
                  v-if="updatePermission">
                  执行
                </el-button>
                <el-button link type="info" @click="handleInfo(scope.row,'view')"
                  v-if="updatePermission && scope.row.result != 1">
                  详情
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <!-- 分页 -->
          <Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNo" :total="total"
            @pagination="getList" />
        </ContentWrap>
      </el-col>
    </el-row>
    <!-- 新增、编辑测试计划 -->
    <UpdateUseCasePlan ref="updateUseCasePlanRef" @success="getPlanList" />
    <!-- 详情 -->
    <Info ref="infoRef" @success="getPlanList" />
  </div>
</template>

<script setup lang="ts">
defineOptions({ name: 'TestPlan' })
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as TestPlanApi from '@/api/testPlan'
import { getProjectMemberRole } from '@/api/demand'
import { FolderOpened, Folder, Document, Edit, Plus } from '@element-plus/icons-vue'
import { useAppStore } from '@/store/modules/app'
import UpdateUseCasePlan from './UpdateUseCasePlan.vue'
import Info from './Info.vue'
const { currentRoute } = useRouter()
const appStore = useAppStore()
const projectId = computed(() => appStore.getSelectProject)
const planList = ref([] as any) // 测试计划列表
const dataSource = ref([] as any) // 树结构（用例集）数据
const defaultProps = {
  children: 'children',
  label: 'name'
}
const loading = ref(false) // 列表的加载中
const total = ref() // 列表的总页数
const list = ref([] as any) // 列表的数据
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  name: '',
  logo: '',
  result: '',
  testSuiteId: '',
  testPlanId: '',
  executeTestUserId: '',
  startTime: [],
  endTime: [],
  testType: '',
  priority: '',
  projectId: projectId.value
})
const queryFormRef = ref() // 搜索的表单
const updateUseCasePlanRef = ref() // 新增用例执行计划
const infoRef = ref() //详情ref
const memberList = ref([] as any) // 用户列表
const role = ref('') // 项目中的角色
const selectPlan = ref() // 选中计划
const defaultId = ref('') // 默认选中id
const addPermission = computed(() => ['admin', 'testManager', 'tester'].includes(role.value))
// const delPermission = computed(() => ['admin', 'testManager', 'tester'].includes(role.value))
const updatePermission = computed(() => ['admin', 'testManager', 'tester'].includes(role.value))

watch(
  () => projectId.value,
  () => {
    // resetData()
    selectPlan.value = ''
    queryParams.projectId = projectId.value
    getProjectMemberRoleFn()
    getPlanList()
    getMembers()
  }
)
const resetData = () => {
  // memberList.value = []
  planList.value = []
  dataSource.value = []
  list.value = []
  // selectPlan.value = ''
  defaultId.value = ''
  total.value = ''
  queryParams.testPlanId = ''
  queryParams.testSuiteId = ''
}
const handleExpand = (node) => {
  if (!node.isLeaf) {
    node.expanded = !node.expanded
  }
}
// 获取计划下拉
const getPlanList = async () => {
  loading.value = true
  resetData()
  try {
    let data = await TestPlanApi.getPlanList({ projectId: projectId.value })
    if (!data) return
    planList.value = data
    selectPlan.value = !selectPlan.value
      ? (planList.value.length
        ? planList.value[0].id
        : '')
      : selectPlan.value
    changePlan(selectPlan.value)
  } finally {
    loading.value = false
  }
}
// 获取人员在项目中角色
const getProjectMemberRoleFn = async () => {
  let data = await getProjectMemberRole({ projectId: projectId.value })
  role.value = data
}
// 获取成员列表
const getMembers = async () => {
  let data = await TestPlanApi.getTestUserList({
    projectId: projectId.value
  })
  memberList.value = data
}
// 切换计划-获取树列表
const changePlan = async (val) => {
  if (!val) return
  loading.value = true
  dataSource.value = []
  defaultId.value = ''
  list.value = []
  total.value = ''
  queryParams.testPlanId = ''
  queryParams.testSuiteId = ''
  try {
    selectPlan.value = val
    let data = await TestPlanApi.getTree({ id: val })
    if (!data) return
    defaultId.value = data.id
    dataSource.value = data ? [data] : []
    handleNodeClick(dataSource.value[0])
  } finally {
    loading.value = false
  }
}
const handleNumClick = (data, result) => {
  if (!data) return
  defaultId.value = data.id
  queryParams.testPlanId = selectPlan.value
  queryParams.testSuiteId = data.id
  queryParams.result = result
  getList()
}
// 点击节点
const handleNodeClick = async (data) => {
  if (!data) return
  defaultId.value = data.id
  queryParams.testPlanId = selectPlan.value
  queryParams.testSuiteId = data.id
  queryParams.result = ''
  getList()
}

// 新增/编辑用例执行计划
const updateUseCasePlan = (type) => {
  updateUseCasePlanRef.value.open(type, selectPlan.value)
}

// 获取表格列表
const getList = async () => {
  loading.value = true
  list.value = []
  try {
    let res = await TestPlanApi.getCaseList(queryParams)
    list.value = res.list
    total.value = res.total
  } finally {
    loading.value = false
  }
}

// 详情
const handleInfo = (row, type) => {
  infoRef.value.open(row, type)
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 初始化 **/
onMounted(() => {
  if (projectId.value) {
    queryParams.projectId = projectId.value
    getPlanList()
    getMembers()
    getProjectMemberRoleFn()
  }
})
</script>

<style lang="scss" scoped>
.plan {
  height: calc(100vh - 175px);

  .el-row {
    height: 100%;

    .el-col {
      height: 100%;

      :deep(.el-card__body) {
        height: calc(100% - 40px);

        >div {
          height: 100%;

          .el-tree {
            height: calc(100% - 30px);
            overflow: auto;
          }
        }
      }
    }
  }
}

.el-row {
  .el-col {
    flex: 1;

    .el-form-item {
      width: 100%;
    }

    .el-date-editor.el-input,
    .el-date-editor.el-input__wrapper {
      width: auto;
    }
  }
}

.num {
  // color: var(--el-color-primary);
  border-radius: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 0px 0 0px;
  font-size: 12px;

  span {
    flex: 1;
    font-size: 12px;
    margin: 0 2px 0;
  }
}

.current {
  display: block;
  background-color: var(--el-color-primary-light-9);
  width: 100%;

  small {
    color: #5e7ce0;
  }
}

:deep(.el-tree) {
  padding: 10px 10px 10px 0;

  .el-tree-node {
    .el-tree-node__content {
      display: flex;
      justify-content: space-between;
    }

    i.el-tree-node__expand-icon {
      svg {
        display: none;
      }
    }

    i.el-tree-node__expand-icon {
      display: none;
    }
  }

  .el-tree-node.is-current {
    .el-tree-node__content {
      small {
        color: #5e7ce0;
      }
    }

    .el-tree-node__children {
      small {
        color: unset;
      }
    }
  }

  /* ^ 树节点 */
  .el-tree-node {
    position: relative;
    width: auto;
    padding-left: 13px;

    &::before {
      width: 1px;
      height: 100%;
      content: '';
      position: absolute;
      top: -38px;
      bottom: 0;
      left: 0;
      right: auto;
      border-width: 1px;
      border-left: 1px solid #b8b9bb;
    }

    &::after {
      width: 13px;
      height: 13px;
      content: '';
      position: absolute;
      z-index: 0;
      left: 0;
      right: auto;
      top: 12px;
      bottom: auto;
      border-width: 1px;
      border-top: 1px solid #b8b9bb;
    }

    .el-tree-node__content {
      position: relative;
      z-index: 1;
      padding-left: 0 !important;
    }

    .el-tree-node__children {
      padding-left: 12px;
    }

    &:last-child::before {
      height: 50px;
    }
  }

  >.el-tree-node {
    padding-left: 0;

    &::before {
      border-left: none;
    }

    &::after {
      border-top: none;
    }
  }
}
</style>
